<template>
  <div class="image-video" :style="scaleStyle" @touchstart="checkDbTouch" @touchend="touchendHandle" @touchmove="touchmoveHandle" @click="clickHandle">
    <template v-if="isVideo">
      <Player v-if="src" :srcset="concatHost(src)" v-bind="$attrs" :poster="concatHost(poster)" :landscape="landscape" :fullscreen="fullscreen" @requestFullscreen="requestFullscreenHandle" @exitFullscreen="exitFullscreenHandle" @click.stop.native @click="clickVideoHandle" />
    </template>
    <div v-else class="img-wrap">
      <van-image
        :src="concatHost(src)"
        width="100%"
        :lazy-load="lazyLoad"
        show-loading
        :fit="fit"
        @load="onImageLoad"
        @error="onImageError"
      >
        <template v-slot:loading>
          <van-loading type="spinner" size="20" />
        </template>
        <template v-slot:error>
          <van-image :src="errorImage" fit="cover" />
        </template>
      </van-image>
      <div v-if="hasUserInfo && watermark" class="watermark-wrap">
        <div class="watermark watermark-item-1">
          <p>{{ account }}</p>
          <p>{{ username }}</p>
        </div>
        <div class="watermark watermark-item-2">
          <p>{{ account }}</p>
          <p>{{ username }}</p>
        </div>
        <div class="watermark watermark-item-3">
          <p>{{ account }}</p>
          <p>{{ username }}</p>
        </div>
        <div class="watermark watermark-item-4">
          <p>{{ account }}</p>
          <p>{{ username }}</p>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import errorPng from '@/assets/error.png'
import Player from '@/components/Player'
import { mapGetters } from 'vuex'
function getDistance(touches) {
  return Math.sqrt(
    (touches[0].clientX - touches[1].clientX) ** 2 +
      (touches[0].clientY - touches[1].clientY) ** 2
  )
}
export default {
  name: 'ImageVideo',
  components: {
    Player
  },
  props: {
    src: {
      type: [String, Array],
      default: '',
      required: true
    },
    poster: {
      type: String,
      default: ''
    },
    isImage: {
      type: Boolean,
      default: true
    },
    errorImage: {
      type: String,
      default: errorPng
    },
    fit: {
      type: String,
      default: 'contain'
    },
    host: {
      type: String,
      default: ''
    },
    landscape: {
      type: Boolean,
      default: false
    },
    fullscreen: {
      type: Boolean,
      default: false
    },
    watermark: {
      type: Boolean,
      default: false
    },
    lazyLoad: {
      type: Boolean,
      default: true
    },
    zooming: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      touche: null,
      scale: 1,
      startScale: 1,
      startX: 0,
      startY: 0,
      moveX: 0,
      moveY: 0,
      backMoveX: 0,
      backMoveY: 0,
      moveing: false,
      scaleing: false,
      startDistance: 1,
      clientX: 0,
      clientY: 0,
      isDbclick: false,
      // 双击
      start: 0,
      id: null,
      func: undefined,
      delay: 200
    }
  },
  computed: {
    isVideo() {
      return !this.isImage
    },
    ...mapGetters(['userInfo']),
    hasUserInfo() {
      return this.userInfo && typeof this.userInfo === 'object'
    },
    account() {
      return this.hasUserInfo ? this.userInfo.account : ''
    },
    username() {
      return this.hasUserInfo ? this.userInfo.userName : ''
    },
    scaleStyle() {
      const scale = this.scale
      const offsetX = this.moveX / scale
      const offsetY = this.moveY / scale
      return {
        transform: `scale(${scale}, ${scale}) translate(${offsetX}px, ${offsetY}px)`
      }
    }
  },
  mounted() {
    this.clientX = window.screen.availWidth
    this.clientY = window.screen.availHeight
  },
  methods: {
    clickHandle() {
      this.$emit('click', this.src, this.isImage)
    },
    concatHost(src) {
      return /^http.+/.test(src) ? src : `${this.host || process.env.VUE_APP_GCENTER_STATIC}/${src}`
    },
    clickVideoHandle() {
      this.$emit('video-click')
    },
    requestFullscreenHandle() {
      this.$emit('requestFullscreen')
    },
    exitFullscreenHandle() {
      this.$emit('exitFullscreen')
    },
    // 双击检测
    checkDbTouch(e) {
      if (e.touches.length < 2) {
        if (this.start === 0) {
          this.start = new Date().getTime()
          this.func = (exe) => {
            this.func = undefined
            if (exe) return
            if (this.scaleing) {
              this.moveHandle(e)
            } else {
              this.$emit('image-video-click')
            }
            this.id = null
            this.start = 0
          }
          this.id = setTimeout(() => {
            if (this.func instanceof Function) {
              this.func()
            }
          }, this.delay)
        } else if (new Date().getTime() - this.start < this.delay) {
          clearTimeout(this.id)
          this.start = 0
          this.id = null
          this.func = undefined
          this.dbTouch(e)
        }
      } else {
        this.id = null
        this.start = 0
        this.scaleHandle(e)
        this.func = undefined
      }
    },
    checkDbTouch1: ((delay) => {
      let start = 0
      let id = null
      return function(e) {
        if (e.touches.length < 2) {
          if (start === 0) {
            start = new Date().getTime()
            id = setTimeout(() => {
              if (this.scaleing) {
                this.moveHandle(e)
              } else {
                this.$emit('image-video-click')
              }
              id = null
              start = 0
            }, delay)
          } else if (new Date().getTime() - start < delay) {
            clearTimeout(id)
            start = 0
            this.dbTouch(e)
          }
        } else {
          id = null
          start = 0
          this.scaleHandle(e)
        }
      }
    })(200),
    dbTouch(e) {
      if (!this.zooming) return
      this.isDbclick = true
      // 放大图片
      if (!this.scaleing) {
        this.$emit('image-video-click', false)
        this.scaleing = true
        this.scale = 1.5
        const touch = e.touches[0]
        const x = touch.clientX < 0 ? 0 : touch.clientX - this.startX
        const y = touch.clientY - this.startY
        if (this.landscape) {
          this.moveX = -y * 0.5
          this.moveY = x * 0.5
        } else {
          this.moveX = -x * 0.5
          this.moveY = -y * 0.5
        }
      } else {
        this.resetScaleMove()
      }
    },
    // 缩放
    scaleHandle(e) {
      if (!this.zooming) return
      if (this.func instanceof Function) {
        this.func(true)
      }
      this.startX = e.touches[0].clientX
      this.startY = e.touches[0].clientY
      this.scaleing = true
      if (this.scaleing) {
        this.startScale = this.scale
        this.startDistance = getDistance(e.touches)
      }
    },
    // 移动
    moveHandle(e) {
      if (!this.zooming || !this.scaleing) return
      if (this.func instanceof Function) {
        this.func(true)
      }
      this.$emit('image-video-click', false)
      this.startX = e.touches[0].clientX
      this.startY = e.touches[0].clientY
      this.backMoveX = this.moveX
      this.backMoveY = this.moveY
      this.moveing = true
    },
    touchendHandle(e) {
      if (this.isDbclick) {
        this.isDbclick = false
        return
      }
    },
    touchmoveHandle(e) {
      if (this.moveing || this.scaleing) {
        e.preventDefault()
      }
      if (this.zooming && e.touches.length === 2) {
        const distance = getDistance(e.touches)
        this.scale = (this.startScale * distance) / this.startDistance
        return
      }
      const touch = e.touches[0]
      if (this.moveing) {
        const x = touch.clientX < 0 ? 0 : touch.clientX - this.startX
        const y = touch.clientY - this.startY
        let moveX
        let moveY
        if (this.landscape) {
          moveX = this.backMoveX + y
          moveY = this.backMoveY - x
          if (this.clientY / 2 - Math.abs(moveX) > 60) {
            this.moveX = moveX
          }
          if (this.clientX / 2 - Math.abs(moveY) > 60) {
            this.moveY = moveY
          }
        } else {
          moveX = this.backMoveX + x
          moveY = this.backMoveY + y
          if (this.clientX / 2 - Math.abs(moveX) > 60) {
            this.moveX = moveX
          }
          if (this.clientY / 2 - Math.abs(moveY) > 60) {
            this.moveY = moveY
          }
        }
      }
    },
    resetScaleMove() {
      this.scale = 1
      this.startScale = 1
      this.moveX = 0
      this.moveY = 0
      this.startDistance = 1
      this.scaleing = false
      this.moveing = false
      this.isDbclick = false
    },
    onImageLoad() {
      this.$emit('load')
    },
    onImageError() {
      this.$emit('load')
    }
  }
}
</script>
<style lang="less">
.image-video{
  font-size: 0;
  height: 100%;
  overflow: hidden;
  // background-color: rgba(0, 0, 0, 0.4);
  .van-image__loading{
    background-color:transparent !important;
  }
  [class*="van-image"]{
    height: 100%;
  }
  [class*="van-image__error"]{
    // height: auto !important;
    position: static;
    background-color:transparent !important;
    .van-image{
      display:flex;
      align-items: center;
      justify-content: center;
    }
    & img{
      object-fit: cover !important;
      max-width: 100%;
      max-height: 100%;
      height: auto;
      width: auto;
    }
  }
  .img-wrap{
    height: 100%;
    position: relative;
    .watermark-wrap{
      position: absolute;
      left: calc(50% + 50px);
      top: 50%;
      transform: translate(-50%,-50%);
    }
    .watermark{
      position: absolute;
      transform: translate(-50%,-50%);
      opacity: 0.4;
      & p{
        margin: 0;
        padding: 0;
        line-height: 20px;
        color: #fff;
        font-size: 16px;
        text-align: center;
      }
    }
    .watermark-item-1{
      top: -110px;
      left: -180px;
      transform: translate(-50%,-50%) rotateZ(-45deg);
    }
    .watermark-item-2{
      top: -110px;
      right: -180px;
      transform: translate(-50%,-50%) rotateZ(-45deg);
    }
    .watermark-item-3{
      bottom: -130px;
      right: -130px;
      transform: translate(-50%,-50%) rotateZ(-45deg);
    }
    .watermark-item-4{
      bottom: -130px;
      left: -230px;
      transform: translate(-50%,-50%) rotateZ(-45deg);
    }
  }
}
</style>
